﻿// *********************************************************************
// [DCOM Productions]
// [Copyright (C) DCOM Productions All rights reserved.]
// *********************************************************************

namespace BitFlex.Xdf {
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using BitFlex.Xdf.Collections;
using System.Xml.XPath;

    /// <summary>
    /// Represents a section of Xdf that can contain one or more elements such as sections, and keys
    /// </summary>
    public class XdfSection {
        /// <summary>
        /// Initializes a new instance of the BitFlex.Xdf.XdfSection class
        /// </summary>
        /// <param name="name">The name of the section</param>
        public XdfSection(string name) {
            this.Name = name;
            this.Keys = new XdfKeyList();
            this.Keys.Owner = this;
            this.Sections = new XdfSectionList();
            this.Sections.Owner = this;
        }

        #region Properties

        /// <summary>
        /// Gets or sets the collection of XdfKey elements
        /// </summary>
        public XdfKeyList Keys {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the name of the section
        /// </summary>
        public string Name {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the parent section that owns this section
        /// </summary>
        public XdfSection Parent {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the collection of XdfSection elements
        /// </summary>
        public XdfSectionList Sections {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the XPath of this Xdf section
        /// </summary>
        public string XPath {
            get {
                if (Parent == null) {
                    return this.Name;
                }
                else {
                    string xpath = string.Format("{0}//{1}",
                        Parent.XPath, this.Name);
                    return xpath;
                }
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Adds a new key to the section
        /// </summary>
        /// <param name="name">The name of the key</param>
        /// <param name="value">The key's value</param>
        public void AddKey(string name, object value) {
            XdfKey key = new XdfKey(name, value);
            Keys.Add(key);
        }

        /// <summary>
        /// Adds a new section to the child sections
        /// </summary>
        /// <param name="name">The name of the section</param>
        public void AddSection(string name) {
            XdfSection item = new XdfSection(name);
            Sections.Add(item);
        }

        /// <summary>
        /// Returns a System.Boolean value indicating whether the specified key exists
        /// </summary>
        /// <param name="name">The name of the key</param>
        /// <returns>Returns true if the key exists, otherwise returns false</returns>
        public bool ContainsKey(string name) {
            return Keys.Find(k => k.Name.ToLower() == name.ToLower()) != null;
        }

        /// <summary>
        /// Returns a System.Boolean value indicating whether the specified section exists
        /// </summary>
        /// <param name="name">The name of the section</param>
        /// <returns>Returns true if the section exists, otherwise returns false</returns>
        public bool ContainsSection(string name) {
            return Sections.Find(s => s.Name.ToLower() == name.ToLower()) != null;
        }

        /// <summary>
        /// Removes one or more keys from the section using the specified name
        /// </summary>
        /// <param name="name">The name of the key(s) to remove</param>
        /// <param name="duplicates">True to remove all keys matching the specified name, otherwise false to remove only a single instance</param>
        public void RemoveKey(string name, bool duplicates) {
            if (duplicates) {
                Keys.RemoveAll(k => k.Name.ToLower() == name.ToLower());
            }
            else {
                Keys.Remove(Keys.First(k => k.Name.ToLower() == name.ToLower()));
            }
        }

        /// <summary>
        /// Removes one or more sections from the child sections using the specified name
        /// </summary>
        /// <param name="name">The name of the section(s) to remove</param>
        /// <param name="duplicates">True to remove all sections matching the specified name, otherwise false to remove only a single instance</param>
        public void RemoveSection(string name, bool duplicates) {
            if (duplicates) {
                Sections.RemoveAll(s => s.Name.ToLower() == name.ToLower());
            }
            else {
                Sections.Remove(Sections.First(s => s.Name.ToLower() == name.ToLower()));
            }
        }

        #endregion
    }
}